#include "InputLayer.hh"
#include "NeuronType.hh"

InputLayer::InputLayer(int x, int y, nemo::Network& net, unsigned start_index)
{
  unsigned il_idx = 0;
  unsigned lsm_idx = net.neuronCount() + 1;
  unsigned res_conn_idx = start_index;

  int delay = 1;
  int weight = 1;
  
 // Input neurons [same as FS for now]
  std::string in_name("InputNeuron");
  int num_in_params = 7;
  float in_params[] = { 0.02, 0.25, -65.0, 2, -13.0, -65.0, 0.0 };
  unsigned input_nemo_type_id = net.addNeuronType(in_name);
  
  IzhikevichNeuronType * inputNeuronType = 
    new IzhikevichNeuronType(input_nemo_type_id, in_name, num_in_params, in_params);
  inputNeuronType->setWeights(1.0, 1.0);


  for(int h = 0; h < y; h++)
    for(int w = 0; w < x; w++)
      {
 	// make new IF at lsm_idx
 	net.addNeuron(input_nemo_type_id, lsm_idx, num_in_params, in_params);
	
 	// connect new IF to Reservoir at res_conn_idx
 	net.addSynapse(lsm_idx, res_conn_idx, delay, weight, false);

 	// add to map <il_idx, lsm_idx>
 	input_reservoir_map_[il_idx] = lsm_idx;

 	//std::cout << lsm_idx << std::endl;

 	res_conn_idx++;
 	il_idx++;
 	lsm_idx++;
      }
}

InputLayer::~InputLayer()
{

}

void InputLayer::update(vector< pair<int,float> > update_list, nemo::Network& net)
{
  float ei_state_idx = 0; // From NeMo docs

  for( vector< pair<int,float> >::iterator it = update_list.begin(); it != update_list.end(); it++)
    {
      unsigned lsm_idx =  input_reservoir_map_[it->first];
      float ei = 1000.0 * it->second;

      net.setNeuronState(lsm_idx, ei_state_idx, ei);
    }
}
